<template>
    <div class="claer" ref="clear">
        
    </div>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import * as TWEEN from "three/examples/jsm/libs/tween.module.js";
import { CSG } from 'three-csg-ts';

let clear = ref();
// 创建场景
const scene = new (THREE as any).Scene();
scene.background = new (THREE as any).Color(0xffffff);

//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);


// 创建渲染器
const render = new THREE.WebGLRenderer({ antialias: true });
render.setSize(600, 400);
render.setPixelRatio(window.devicePixelRatio);
render.setClearColor(0xffffff, 1);

// 创建相机
const camera = new (THREE as any).PerspectiveCamera(45, 600 / 400, 0.1, 1000);
const bestLength = 80
camera.position.x = bestLength;
camera.position.y = bestLength;
camera.position.z = bestLength;
camera.lookAt(0, 0, 0);

// 轨道滑动器
const controls = new OrbitControls(camera, render.domElement); //轨道滑动器
controls.enableDamping = true;  // 设置带阻尼的惯性
controls.dampingFactor = 0.1; // 设置阻尼系数
controls.rotateSpeed = 0.14; // 旋转速度

// 创建灯光
const createLight = (x: number, y: number, z: number) => {
    const color = 0xffffff; //  灯光颜色
    const intensity = 1; // 灯光强度
    const light = new (THREE as any).DirectionalLight(color, intensity);
    light.position.set(x, y, z);
    light.target.position.set(0, 0, 0);
    return light;
};
const lights = [
    createLight(bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, -bestLength),
    createLight(-bestLength, bestLength, bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, -bestLength),
    createLight(-bestLength, -bestLength, bestLength),
    createLight(bestLength, -bestLength, bestLength),
];
lights.forEach((light) => scene.add(light));
lights.forEach((light) => scene.add(light.target)); 

const CONSTANTS = {
  CYLINDER_SEGMENTS: 32,
  ANIMATION_DURATION: 3000
};
// 创建 圆柱模型  函数
const createCylinder = (radiusTop:number, radiusBottom:number, height:number, position = new THREE.Vector3(0, 0, 0), material = new THREE.MeshNormalMaterial()) => { 
    // const geometry = new (THREE as any).CylinderGeometry(radiusTop, radiusBottom, height, radialSegments);
    const geometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height, CONSTANTS.CYLINDER_SEGMENTS);
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.copy(position);
    return mesh;
};

const createConduit = (externalRadius:number, internalRadius:number, height:number, position:THREE.Vector3) => {
  const externalGeometry = createCylinder(externalRadius, externalRadius, height);
  const internalGeometry = createCylinder(internalRadius, internalRadius, height);
  externalGeometry.updateMatrixWorld();
  internalGeometry.updateMatrixWorld();
  let subResult = CSG.subtract(externalGeometry, internalGeometry);
  subResult.position.copy(position);
  return subResult;
};

let blank: THREE.Mesh | null = null;      // 毛坯模型
let Geometries: THREE.Mesh[] = [];    // 加工几何体数组
let GeometriesLengths:number[] = []; // 几何体位置数组
let nowCube : THREE.Mesh;        // 当前显示的模型
let currentSubResult: THREE.Mesh | null = null; // 当前布尔运算结果
let animationTime:number[] = [3000,2000,1000];    // 动画时间数组
let index = 0;             // 当前动画索引
let isAnimating = false;   // 动画状态标志
const analysis = ref(8);   // 分析值（半径）
const blankHeight = ref(64); // 毛坯高度

const blankData = { radius: 30, length: 60 };
const loadBlank = (blankData:any) => {
  analysis.value = blankData.radius;
  blankHeight.value = blankData.length;
  
  blank = createCylinder(
    analysis.value,         // 顶部半径
    analysis.value,         // 底部半径（相同=圆柱）
    blankData.length,       // 高度
    new THREE.Vector3(0, blankData.length / 2 , 0) // 位置
  );
}

const loadGeometries = () => {
    Geometries = [
        createConduit(analysis.value, analysis.value - analysis.value / 4, blankHeight.value, new THREE.Vector3(0, blankHeight.value, 0)),
        createConduit(analysis.value - analysis.value / 4, analysis.value / 2, blankHeight.value, new THREE.Vector3(0, blankHeight.value, 0)),
        createConduit(analysis.value - analysis.value / 2, analysis.value / 4 , blankHeight.value, new THREE.Vector3(0, blankHeight.value, 0))
    ]
    GeometriesLengths = [
        // 定义刀具终点y轴位置 毛坯的相当于剩余长度
        blankHeight.value / 4,
        blankHeight.value / 2,
        blankHeight.value * 3 / 4,
    ]
}

// const loadGeometries = (machineData) => {

//     let length = 0;
//     machineData.forEach(item => {
//     length += item.length;
//     });
//     Geometries = [];
//     GeometriesLengths = [];
//     for (let item = 0; item < machineData.length; item++) {
//     const circle = machineData[item];
//     const geometry = createConduit(analysis.value, circle.radius, length, new THREE.Vector3(0, blankHeight.value / 2, 0));
//     Geometries.push(geometry);
//     animationTime.push(length * 100)
//     console.log('nowy', length / 2);
//     GeometriesLengths.push(-length / 2 + circle.length / 2);
//     length -= circle.length;
//     }
// }

// 添加模型和刀具到场景中
const addInputGeometry = async () => {
    nowCube = blank as THREE.Mesh;
    if (nowCube) {
        nowCube.material = new THREE.MeshNormalMaterial();
    } else {
        console.error('模型未正确加载');
    }
    scene.add(nowCube);
    console.log(nowCube)
    // const cylinder = createCylinder(analysis.value, analysis.value,  2, new THREE.Vector3(0, 5 + 1, 0));
    // scene.add(cylinder);
    // const cylinderTween = new TWEEN.Tween(cylinder.scale).to({ x: 0, y: 1, z: 0 }, CONSTANTS.ANIMATION_DURATION);
    // cylinderTween.start();
};

//  布尔运算开始切削圆柱体
const animateLoop = async () => { 
    // 显示刀具的原始位置
    // Geometries.forEach((geometry) => {
    //     // 为每个空心圆柱设置材质（使用半透明材质便于观察）
    //     const material = new THREE.MeshBasicMaterial({
    //         color: 0xff0000, 
    //         transparent: true,
    //         opacity: 0.5
    //     });
        
    //     // 创建网格并添加到场景
    //     const mesh = new THREE.Mesh(geometry.geometry, material);
    //     mesh.position.copy(geometry.position);
    //     scene.add(mesh);
    // });

    if (index >= Geometries.length) {
        isAnimating = false;
        return;
    }
    scene.remove(nowCube);
    const internalGeometry = Geometries[index];
    const material = new THREE.MeshBasicMaterial({
            color: 0xff0000, 
            transparent: true,
            opacity: 0.2
        });
    internalGeometry.material = material;
    const endY = GeometriesLengths[index];

    new TWEEN.Tween(internalGeometry.position)
        .to({ y: endY }, animationTime[index])
        .onUpdate(() => {
            internalGeometry.updateMatrixWorld();
            scene.remove(currentSubResult);
            currentSubResult = CSG.subtract(nowCube, internalGeometry);
            scene.add(currentSubResult);
            // 显示刀具
            // scene.add(internalGeometry);
        })
        .onComplete(() => {
            nowCube = currentSubResult as THREE.Mesh;
            index++;
            isAnimating = false;
            animateLoop();
        })
        .start();
};

//  渲染函数
const animate = () => {
    controls.update(); // 轨道滑动器更新
    requestAnimationFrame(animate); // 递归调用
    render.render(scene, camera); // 渲染
    (TWEEN as any).update(); // 更新动画
};


// 挂载
onMounted(() => {
    clear.value.appendChild(render.domElement);
    animate();
    
    loadBlank(blankData);
    loadGeometries();
    addInputGeometry(); 
    animateLoop();
});
</script>

<style lang="less">
.claer {
    width: 600px;
    height: 460px;
    border: 1px solid #ccc;
}
</style>